home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / KBM.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  10KB  |  253 lines

  1. ;---------------------------------------------------------------------------
  2. ;KBM KeyBoard Mouse            by Dan Rollins                       5-20-85
  3. ;
  4. ; This program intercepts keyboard data and creates a bit pattern determined
  5. ; according to whether or not certain keys are currently being pressed.
  6. ;
  7. ; The bit pattern is stored in the "inter-application communication area"
  8. ;  at 0000:04f0.  It is interpreted as:
  9. ;
  10. ;  7 6 5 4 3 2 1 0   (bit number)
  11. ;  C m P H l d r u   (bit name)
  12. ;  | | | | | | | |
  13. ;  | | | | | | | +- bit 0 (01h) - set = 1 while [up arrow] is pressed
  14. ;  | | | | | | +--- bit 1 (02h) - set = 1 while [right arrow] is pressed
  15. ;  | | | | | +----- bit 2 (04h) - set = 1 while [down arrow] or [5] is pressed
  16. ;  | | | | +------- bit 3 (08h) - set = 1 while [left arrow] is pressed
  17. ;  | | | |
  18. ;  | | | +--------- bit 4 (10h) - set = 1 while [Home] is pressed
  19. ;  | | +----------- bit 5 (20h) - set = 1 while [PgUp] is pressed
  20. ;  | +------------- bit 6 (40h) - set = 1 while grey [-] is pressed
  21. ;  +--------------- bit 7 (80h) - set = 1 while [CapsLock] is pressed
  22. ;
  23. ; As soon as the key is released, the relevant bit is reset to 0.
  24. ;
  25. ; The byte at 0000:04f1 is the "pass-through/filter" mode flag.  When this
  26. ; byte is zero, all keystrokes are passed to the normal keyboard handler.
  27. ; When it's non-zero, the selected keystrokes are filtered (disabled for
  28. ; normal input).  BIOS and DOS keyboard calls will not recognize them.
  29. ;
  30. ; The Alt-NumLock keystroke toggles between pass-through and filter modes.
  31. ;
  32. ; This program is installed and remains resident.  It is a COM-format
  33. ; file, so it must be converted with EXE2BIN.
  34. ;
  35. ; Copyright (c) Ziff-Davis Publishing Co., 1986.  All rights reserved.  
  36. ;
  37. ;= equates ===============
  38.  
  39. KB_DATA_PORT  equ     60h  ;These are listed in the PC and XT
  40. KB_CTRL_PORT  equ     61h  ; Technical Reference Manuals
  41.  
  42. KB_FLAG       equ    417h  ; the BIOS shift-key status (in segment 0)
  43. ALT_STATE     equ      8   ;  Bit pattern while the [Alt] key is pressed
  44. NUMLOCK_KEY   equ     69   ;  scan-code of the [NumLock] key
  45.  
  46. INT_CTL_PORT  equ     20h  ; Interrupt controller port (8259 chip)
  47. EOI           equ     20h  ; End-Of-Interrupt code sent to 8259
  48.  
  49. RELEASE_BIT   equ     80h  ;also called the "break" bit: a key was released
  50.  
  51. KEY_BITS      equ     04f0H ;the address of the key bit flags (segment 0)
  52. MODE_FLAG     equ     04f1H ;when 0, all keys are passed to normal kbint
  53. INST_FLAG     equ     04f2H ; set to 1234H during installation
  54.  
  55. com_seg  segment
  56.          assume  cs:com_seg, ds:com_seg
  57.          org     100h                    ;must have for COM-format program
  58. kbm      proc    far
  59.          jmp     set_up    ;get past data and install interrupt hander
  60.  
  61. ;============= program data area ========
  62.  
  63. norm_kbd_int  label dword   ;type DWORD so it can be used in a FAR jump
  64. nki_offset    dw    0       ; This address is stored in the SET_UP proc
  65. nki_segment   dw    0       ; It's the address of the previous kbint routine
  66.  
  67. ;-----------------------------------------------------------------------------
  68. ; KBD_INT
  69. ; 1) read the keyboard
  70. ; 2) set/reset bits in mouse movement byte
  71. ; 3) execute normal keyboard interrupt
  72. ;
  73. ;          scan  bit     key         suggested  meaning
  74. ;          code  flag    name        (defined by user)
  75. ;          ---- ----     ---------  ----------------------
  76. kbm_tbl  db  72, 1  ;    num.pad 8   go up
  77.          db  77, 2  ;    num.pad 6   go right
  78.          db  80, 4  ;    num.pad 2   go down
  79.          db  75, 8  ;    num.pad 4   go left
  80.  
  81.          db  76, 4  ;    num.pad 5   go down
  82.          db  71, 16 ;    Home        button 1
  83.          db  73, 32 ;    PgUp        button 2
  84.          db  74, 64 ;    grey minus  button 3
  85.          db  58, 128;    CapsLock    "high-gear shift" for fast motion
  86. tbl_end  label byte
  87.  
  88. ;-----------------------------------------------------------------------------
  89. ; KBD_INT
  90. ; This procedure intercepts the ROM-BIOS KB_INT.
  91. ; It sets and resets bits of a kbd flag as the user presses and releases keys.
  92. ; When the byte at 0000:04F1 is 0, the keystroke is passed on to the
  93. ; original keyboard handler.
  94.  
  95. kbd_int  proc    far
  96.          sti
  97.          cld
  98.          push    ax
  99.          push    si
  100.          push    ds
  101.  
  102.          in      al,KB_DATA_PORT ;read scan-code from keyboard into AL
  103.          mov     ah,al           ;save original byte in AH
  104.          and     al,7fh          ;mask off "release bit" for comparisons
  105.  
  106.          mov     si,offset kbm_tbl
  107. k_20:
  108.          cmp     si,offset tbl_end   ;at end of table?
  109.          ja      k_25                ; yes, key not found. Exit to normal kbint
  110.          cmp     al,byte ptr cs:[si] ; is this the key?
  111.          je      k_30                ;   yes, process the keystroke
  112.          inc     si                  ;   no, point past the scan code
  113.          inc     si                  ;       point past the bit-mask
  114.          jmp     k_20                ;       and loop back for the next entry
  115.  
  116. k_25:
  117. ;------- check for mode-toggle by user
  118.          cmp     ah,NUMLOCK_KEY                  ;is this a press of [NumLock]?
  119.          jne     k_27                            ;  no, go
  120.          sub     si,si                           ;  yes, look to BIOS data area
  121.          mov     ds,si
  122.          test    byte ptr ds:[KB_FLAG],ALT_STATE ;  is [Alt] pressed?
  123.          jz      k_27                            ;    no, pass the key on
  124.  
  125.          xor     byte ptr ds:[MODE_FLAG],1       ;    yes, toggle the mode and
  126.          jmp    short k_exit                     ;         exit w/o processing
  127.  
  128. ;------- the keystroke is to be processed by the normal keyboard interrupt
  129. k_27:
  130.          pop     ds
  131.          pop     si
  132.          pop     ax
  133.          jmp     cs:[norm_kbd_int]       ;continue at normal keyboard handler
  134.  
  135. k_30:
  136. ;------- process the scan code into a bit-pattern
  137.          mov     al,cs:[si+1]     ;get bit-flag mask
  138.  
  139.          sub     si,si
  140.          mov     ds,si            ;point to segment of KEY_BITS
  141.  
  142.          test    ah,RELEASE_BIT   ;is this key being released?
  143.          jz      k_40             ; no, go
  144.  
  145. ;------- process key release
  146.          not     al                           ;flip-flop mask bits
  147.          and     byte ptr ds:[KEY_BITS],al    ;mask off released key bit
  148.          jmp     k_50
  149. k_40:
  150. ;------- process key press
  151.          or      byte ptr ds:[KEY_BITS],al    ;set the bit for pressed key
  152.  
  153. ;------- determine whether key should be passed on to normal keyboard handler
  154. k_50:
  155.          cmp     byte ptr ds:[MODE_FLAG],0    ;should key be processed further?
  156.          je      k_27                         ; yes, continue at normal kb int
  157.  
  158. ;------- the keystroke is to be ignored by the rest of the system.
  159. ;------- wrap up this keyboard interrupt.
  160.  
  161. k_exit:
  162.          in      al,KB_CTRL_PORT ;get current value of keyboard control lines
  163.          mov     ah,al           ; save it
  164.          or      al,80h          ;set the "enable kbd" bit
  165.          out     KB_CTRL_PORT,al ; and write it out the control port
  166.          xchg    ah,al           ;fetch the original control port value
  167.          out     KB_CTRL_PORT,al ; and write it back
  168.  
  169.          pop     ds
  170.          pop     si
  171.  
  172.          cli
  173.          mov     al,EOI           ;send End-Of-Interrupt signal
  174.          out     INT_CTL_PORT,al  ; to the 8259 Interrupt Controller
  175.          pop     ax
  176.          iret                     ;exit to interrupted program
  177. kbd_int  endp
  178.  
  179. LAST_BYTE equ   offset $+1  ;This is the address passed to INT 27H
  180.                             ;Notice that the code of the SET_UP
  181.                             ;  procedure is not preserved in memory
  182.  
  183. ;-----------------------------------------------------------------------------
  184. ; SET_UP
  185. ; This routine is executed only once, when the program is installed.
  186.  
  187. inst_msg db 'KBM  KeyBoard Mouse driver',0dh,0ah
  188.          db 'Copyright (c) 1986 Ziff-Davis Publishing Co.,',0dh,0ah,'$'
  189.  
  190. err_msg1 db 07,'Already installed',0dh,0ah,'$'
  191. err_msg2 db 'Wrong DOS version.',0dh,0ah,'$'
  192.  
  193. set_up   proc    near
  194.  
  195. ;------- make sure this is DOS 2.0 or later
  196.          mov     ah,30h
  197.          int     21h
  198.          cmp     al,2
  199.          jae     su_10
  200.          mov     dx,offset err_msg2
  201.          jmp     msg_exit
  202. su_10:
  203.  
  204. ;------- see if KBM has already been installed
  205.          mov     ax,0
  206.          mov     es,ax
  207.          cmp     es:[INST_FLAG],1234H  ;already installed?
  208.          jne     su_20                 ;  no, continue
  209.          mov     dx,offset err_msg1    ;  yes, exit with message
  210.          jmp     msg_exit
  211. su_20:
  212.          mov     word ptr es:[INST_FLAG],1234h  ; flag says KBM is installed
  213.  
  214. ;------- save the old kbint vector and set up the new one
  215.          mov     al,9
  216.          mov     ah,35h         ;DOS GET_VECTOR service
  217.          int     21h            ; for interrupt 9 (KBINT)
  218.  
  219.          mov     al,9           ;get address of the current kb int handler
  220.          mov     ah,35h         ;DOS GET_VECTOR service
  221.          int     21h
  222.          mov     nki_segment,es ;save old address
  223.          mov     nki_offset,bx
  224.  
  225.          mov     dx,offset kbd_int  ;set INT 9 to local keyboard interceptor
  226.          mov     al,9               ;set vector for INT 9 to DS:DX
  227.          mov     ah,25h             ;DOS SET_VECTOR service
  228.          int     21h
  229.  
  230.          mov     ax,0
  231.          mov     es,ax                          ;initialize variables:
  232.          mov     byte ptr es:[MODE_FLAG],0      ; process all keystrokes
  233.          mov     byte ptr es:[KEY_BITS],0       ; no keys are pressed
  234.  
  235. ;------- display message to indicate install`tion complete
  236.          mov     dx,offset inst_msg
  237.          mov     ah,9
  238.          int     21h
  239.  
  240. ;------- exit to DOS, leaving the interrupt handler resident
  241.          mov     dx,LAST_BYTE
  242.          int     27h
  243.  
  244. msg_exit:
  245.          mov     ah,9
  246.          int     21h
  247.          int     20h
  248. set_up   endp
  249. kbm      endp
  250. com_seg  ends
  251.          end     kbm
  252.  
  253.